/*
** Copyright (C) 2010 Calin Radoni
**
** This file is part of CHScanner.
**
** CHScanner is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** CHScanner is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with CHScanner. If not, see <http://www.gnu.org/licenses/>.
*/

#include "StdAfx.h"
#include "MWmi_Win32_PhysicalMemory.h"

//---------------------------------------------------------------------------

MWmi_Win32_PhysicalMemory::MWmi_Win32_PhysicalMemory(void)
{
	propertyCount = 11;
	Initialize();
}

MWmi_Win32_PhysicalMemory::~MWmi_Win32_PhysicalMemory(void)
{
	DeleteChild();
}

//---------------------------------------------------------------------------

MWmiInfo* MWmi_Win32_PhysicalMemory::CreateChild(void)
{
	MWmi_Win32_PhysicalMemory *elem;

	try{
		elem = new MWmi_Win32_PhysicalMemory;
	}
	catch(...){
		elem = NULL;
	}
	return elem;
}

void MWmi_Win32_PhysicalMemory::DeleteChild(void)
{
	MWmi_Win32_PhysicalMemory *elem;
	
	if(next!=NULL){
		elem = (MWmi_Win32_PhysicalMemory*)next;
		next = NULL;
		delete elem;
	}
}

//---------------------------------------------------------------------------

void MWmi_Win32_PhysicalMemory::Initialize(void)
{
	xCapacity      = _T("");
	xDataWidth     = 0;
	xDescription   = _T("");
	xDeviceLocator = _T("");
	xFormFactor    = 0;
	xMemoryType    = 0;
	xName          = _T("");
	xSpeed         = 0;
	xTag           = _T("");
	xTotalWidth    = 0;
	xTypeDetail    = 0;
}

//---------------------------------------------------------------------------

CString MWmi_Win32_PhysicalMemory::GetQueryString(void)
{
	CString str;

	str = _T("select * from Win32_PhysicalMemory");
	return str;
}

//---------------------------------------------------------------------------

CString MWmi_Win32_PhysicalMemory::GetPropertyName(int idxIn)
{
	CString str;

	switch(idxIn){
		case 0 :
			str = _T("Capacity");
			break;
		case 1 :
			str = _T("DataWidth");
			break;
		case 2 :
			str = _T("Description");
			break;
		case 3 :
			str = _T("DeviceLocator");
			break;
		case 4 :
			str = _T("FormFactor");
			break;
		case 5 :
			str = _T("MemoryType");
			break;
		case 6 :
			str = _T("Name");
			break;
		case 7 :
			str = _T("Speed");
			break;
		case 8 :
			str = _T("Tag");
			break;
		case 9 :
			str = _T("TotalWidth");
			break;
		case 10 :
			str = _T("TypeDetail");
			break;

		default :
			str = _T("");
			break;
	}

	return str;
}

//---------------------------------------------------------------------------

bool MWmi_Win32_PhysicalMemory::SetPropertyValue(int idxIn, VARIANT *vtIn)
{
	if(vtIn==NULL) return true;
	if(vtIn->vt==VT_NULL) return true;

	switch(idxIn){
		case 0 :
			if(vtIn->vt!=VT_BSTR) return false;
			xCapacity = vtIn->bstrVal;
			break;
		case 1 :
			if(vtIn->vt!=VT_I4) return false;
			xDataWidth = (unsigned short)vtIn->lVal;
			break;
		case 2 :
			if(vtIn->vt!=VT_BSTR) return false;
			xDescription = vtIn->bstrVal;
			break;
		case 3 :
			if(vtIn->vt!=VT_BSTR) return false;
			xDeviceLocator = vtIn->bstrVal;
			break;
		case 4 :
			if(vtIn->vt!=VT_I4) return false;
			xFormFactor = (unsigned short)vtIn->lVal;
			break;
		case 5 :
			if(vtIn->vt!=VT_I4) return false;
			xMemoryType = (unsigned short)vtIn->lVal;
			break;
		case 6 :
			if(vtIn->vt!=VT_BSTR) return false;
			xName = vtIn->bstrVal;
			break;
		case 7 :
			if(vtIn->vt!=VT_I4) return false;
			xSpeed = vtIn->lVal;
			break;
		case 8 :
			if(vtIn->vt!=VT_BSTR) return false;
			xTag = vtIn->bstrVal;
			break;
		case 9 :
			if(vtIn->vt!=VT_I4) return false;
			xTotalWidth = (unsigned short)vtIn->lVal;
			break;
		case 10 :
			if(vtIn->vt!=VT_I4) return false;
			xTypeDetail = (unsigned short)vtIn->lVal;
			break;

		default :
			return false;
	}

	return true;
}

//---------------------------------------------------------------------------

bool MWmi_Win32_PhysicalMemory::SetFromPointer(MWmiInfo* wmiInfoIn)
{
	MWmi_Win32_PhysicalMemory *elem;
	MWmi_Win32_PhysicalMemory *elemNew;

	DeleteChild();
	Initialize();
	if(wmiInfoIn==NULL) return true;

	elem = (MWmi_Win32_PhysicalMemory*)wmiInfoIn;

	xCapacity      = elem->xCapacity;
	xDataWidth     = elem->xDataWidth;
	xDescription   = elem->xDescription;
	xDeviceLocator = elem->xDeviceLocator;
	xFormFactor    = elem->xFormFactor;
	xMemoryType    = elem->xMemoryType;
	xName          = elem->xName;
	xSpeed         = elem->xSpeed;
	xTag           = elem->xTag;
	xTotalWidth    = elem->xTotalWidth;
	xTypeDetail    = elem->xTypeDetail;

	if(elem->next==NULL) return true;

	try{
		elemNew = new MWmi_Win32_PhysicalMemory;
	}
	catch(...){
		elemNew = NULL;
	}
	if(elemNew==NULL) return false;

	next = elemNew;

	return elemNew->SetFromPointer(elem->next);
}

//---------------------------------------------------------------------------

int MWmi_Win32_PhysicalMemory::GetTotalSizeM(void)
{
	return GetTotalSizeMbyType(0xFFFF);
}

int MWmi_Win32_PhysicalMemory::GetTotalSizeMbyType(unsigned short memoryTypeIn)
{
	MWmi_Win32_PhysicalMemory *elem;
	int retVal;
	bool err;
	unsigned __int64 val64;

	elem = this;
	retVal = 0;
	err = false;
	while(elem!=NULL){
		if(elem->xMemoryType==memoryTypeIn || memoryTypeIn==0xFFFF){
			val64 = _tcstoui64(elem->xCapacity, NULL, 10);
			if(val64==_UI64_MAX) err = true;
			else                 retVal += (int)(val64>>20);
		}
		elem = (MWmi_Win32_PhysicalMemory*)elem->next;
	}

	return err ? 0 : retVal;
}

//---------------------------------------------------------------------------

bool MWmi_Win32_PhysicalMemory::IsEmpty(void)
{
	return xName.IsEmpty() ? true : false;
}

//---------------------------------------------------------------------------
